#include "database.h"

CDatabase::CDatabase(void)
{
	
}
CDatabase::~CDatabase(void)
{

}
std_method_impl CDatabase::Connect(LPCSTR dbpath)
{
	try
	{
		m_pSqlite3.open(dbpath);
	}
	catch (CppSQLite3Exception& e)
	{
		loge("open %s==>error_code", dbpath, e.errorCode());
		return E_FAIL;
	}

	m_strDBPath.clear();
	m_strDBPath.append(dbpath);

	return S_OK;
}
std_method_type_impl(UINT) CDatabase::IsValid()
{
	return S_SUCCESS;
}
std_method_impl CDatabase::Close()
{

	m_pSqlite3.close();
	return S_OK;
}

std_method_impl CDatabase::IsTableExist(LPCSTR strTableName, UINT& Exist)
{
	rc_assert(strTableName != NULL, E_FAIL)

	std::string sql = "SELECT name FROM sqlite_master where type ='table' and name ='";
	sql += strTableName;
	sql += "'";

	Exist = S_ERROR;

	try
	{
		CppSQLite3Table table = m_pSqlite3.getTable(sql.c_str());
		int count = table.numFields();

		const char* pName = table.getStringField(0);
		if (s_stricmp(pName, strTableName) == 0 ) {

			Exist = S_SUCCESS;
		}
	}
	catch (CppSQLite3Exception& e)
	{
		loge("get_table %s==>error_code %d", strTableName, e.errorCode());
		Exist = S_ERROR;
		return S_OK;
	}
	return S_OK;
}


std_method_type_impl(std::string) CDatabase::GetDbPath()
{
	return m_strDBPath;
}

std_method_impl CDatabase::GetTableStruct(LPCSTR strTableName, vector<string>& VecField)
{
	int nRow = 0, nColumn = 0;
	char *errmsg = NULL;

	std::string sql = "PRAGMA table_info(";
	sql += strTableName;
	sql += ")";

	try
	{
		CppSQLite3Table table = m_pSqlite3.getTable(sql.c_str());

		int loop = 0;
		for (loop = 0; loop < table.numRows(); loop++)
		{
			table.setRow(loop);
			const char* pChar = table.fieldValue("name");
			VecField.push_back(pChar);
		}
	}
	catch (CppSQLite3Exception& e)
	{
		loge("get_table_struct %s==>error_code %d", strTableName, e.errorCode());
		return S_OK;
	}

	return S_OK;
}

std_method_impl CDatabase::ExeSql(LPCSTR sql)
{

	rc_assert(sql != NULL, E_FAIL)

	try
	{
		int row = m_pSqlite3.execDML(sql);
		logi("CDatabase::ExeSql");
		
	}
	catch (CppSQLite3Exception& e)
	{
		loge("ExeSql %s==>error_code %d", sql, e.errorCode());
		return E_FAIL;
	}

	return S_OK;
}

std_method_impl CDatabase::InsertSql(LPCSTR sql, vector<varaint_t*>& VecParams, Table& table, ULONG stm, ULONG ltm)
{
	rc_assert(sql != NULL, E_FAIL)
	//rc_assert(VecParams.size() == table.size(), E_FAIL)

	try
	{
		m_pSqlite3.execDML("begin transaction;");

		CppSQLite3Statement  stmt = m_pSqlite3.compileStatement(sql);


		stmt.bind(1, (int)stm);
		stmt.bind(2, (int)ltm);

		UINT uloop = 0;
		for (uloop = 0; uloop < VecParams.size(); uloop++)
		{
			if (s_stricmp(table[uloop].type, FIELD_TYPE_STRING) == 0) {
				stmt.bind(uloop + 3, VecParams[uloop]->pszVal);
			}
			else if (s_stricmp(table[uloop].type, FIELD_TYPE_INT) == 0) {
				stmt.bind(uloop + 3, (int)VecParams[uloop]->ulVal);
			}
		}

		stmt.execDML();
		stmt.reset();
		stmt.finalize();

		m_pSqlite3.execDML("commit transaction;");

		logi("CDatabase::ExeSql");
	}
	catch (CppSQLite3Exception& e)
	{
		loge("ExeSql %s==>error_code %d", sql, e.errorCode());
		return E_FAIL;
	}

	return S_OK;
}



